/*
 * Widget.cpp
 *
 *  Created on: 09/12/2011
 *      Author: Tales
 */
#include "Widget.hpp"

namespace yep
{
Widget::Widget()
{
	parent = NULL;
	focused = false;
	topBorder = bottomBorder = rightBorder = leftBorder = 0;
	style = &StyleBaseOld::defaultStyle();
	style->defaultColors(textColor, backgroundColor);
}

Widget::~Widget()
{
}
void Widget::onChildSizeChange(Widget & child, const Rect & newArea)
{
	//A temporary variable storing the position and the dimension of the child.
	Rect newAbsoluteRect(newArea);
	//A temporary variable storing the position and the dimension of the _parent.
	Rect absoluteArea(absolutePosition.x + leftBorder,
			absolutePosition.y + topBorder,
			absoluteRect.w() - (leftBorder + rightBorder),
			absoluteRect.h() - (topBorder + bottomBorder));
	//Adjusting the relative to absolute.
	newAbsoluteRect.x() += absoluteArea.x();
	newAbsoluteRect.y() += absoluteArea.y();
	//Killing the extra right _area.
	if (newAbsoluteRect.getX2() > newAbsoluteRect.getX2())
	{
		Sint32 difX = newAbsoluteRect.getX2() - absoluteArea.getX2();
		newAbsoluteRect.setW(
				newAbsoluteRect.w() > difX ? newAbsoluteRect.w() - difX : 0);
	}
	//Killing the extra down
	if (newAbsoluteRect.getY2() > absoluteArea.getY2())
	{
		Sint32 difY = newAbsoluteRect.getY2() - absoluteArea.getY2();
		newAbsoluteRect.setH(
				newAbsoluteRect.h() > difY ? newAbsoluteRect.h() - difY : 0);
	}
	//The absolute position and Area
	Vector2 newAbsolutePosition(newAbsoluteRect);
	Rect newAbsoluteArea(0, 0, newAbsoluteRect.w(), newAbsoluteRect.h());
	//Killing the extra left
	if (newAbsolutePosition.x < absolutePosition.x)
	{
		int difX = absolutePosition.x - newAbsolutePosition.x;
		newAbsolutePosition.x = absolutePosition.x;
		newAbsoluteArea.setX(difX);
		newAbsoluteArea.setW(
				newAbsoluteArea.w() > difX ? newAbsoluteArea.w() - difX : 0);
	}
	//Killing the extra up
	if (newAbsolutePosition.y < absolutePosition.y)
	{
		int difY = absolutePosition.y - newAbsolutePosition.y;
		newAbsolutePosition.y = absolutePosition.y;
		newAbsoluteArea.setY(difY);
		newAbsoluteArea.setH(
				newAbsoluteArea.h() > difY ? newAbsoluteArea.h() - difY : 0);
	}
	child.setAbsolutePosition(newAbsolutePosition);
	child.setAbsoluteArea(newAbsoluteArea);
}
bool Widget::onEvent(SDL_Event & event)
{
	switch (event.type)
	{
	case SDL_MOUSEBUTTONDOWN:
		if (event.button.button
				& (SDL_BUTTON_LEFT | SDL_BUTTON_RIGHT | SDL_BUTTON_MIDDLE))
		{
			Rect absoluteArea(absolutePosition.x, absolutePosition.y,
					absoluteRect.w(), absoluteRect.h());
			if (event.button.x >= absoluteArea.x()
					&& event.button.x <= absoluteArea.getX2()
					&& event.button.y >= absoluteArea.y()
					&& event.button.y <= absoluteArea.getY2())
			{
				setFocused(true);
				return onClickDown(event.button);
			}
			else
				setFocused(false);
		}
		break;
	}
	return false;
}

bool Widget::onClickDown(SDL_MouseButtonEvent & buttonEvent)
{
	return false;
}

void Widget::onChildFocusChange(Widget & child, bool gained)
{
	return;
}

const Rect & Widget::getRect() const
{
	return rect;
}

void Widget::setRect(const Rect & value)
{
	rect = value;
	if (parent)
		parent->onChildSizeChange(*this, value);

	else
	{
		setAbsolutePosition(Vector2(value));
		setAbsoluteArea(Rect(0, 0, value.getW(), value.getH()));
	}
}

Vector2 Widget::getPosition() const
{
	return Vector2(rect);
}

void Widget::setPosition(const Vector2 & value)
{
	rect.setX(value.x);
	rect.setY(value.y);
	if (parent)
		parent->onChildSizeChange(*this, rect);

	else
		absolutePosition = value;

}
const Vector2 & Widget::getAbsolutePosition() const
{
	return absolutePosition;
}

void Widget::setAbsolutePosition(const Vector2 & value)
{
	absolutePosition = value;
}

const Rect & Widget::getAbsoluteArea() const
{
	return absoluteRect;
}

void Widget::setAbsoluteArea(const Rect & value)
{
	absoluteRect = value;
}

Widget *Widget::getParent() const
{
	return parent;
}

void Widget::setParent(Widget *value)
{
	parent = value;
	if (parent)
		parent->onChildSizeChange(*this, rect);

}
bool Widget::isFocused() const
{
	return focused;
}

void Widget::setFocused(bool value)
{
	if (focused != value)
	{
		focused = value;
		if (parent)
			parent->onChildFocusChange(*this, value);

	}
}

Uint8 Widget::getLeftBorder() const
{
	return leftBorder;
}

void Widget::setLeftBorder(Uint8 value)
{
	leftBorder = value;
}

Uint8 Widget::getRightBorder() const
{
	return rightBorder;
}

void Widget::setRightBorder(Uint8 value)
{
	rightBorder = value;
}

Uint8 Widget::getTopBorder() const
{
	return topBorder;
}

void Widget::setTopBorder(Uint8 value)
{
	topBorder = value;
}

Uint8 Widget::getBottomBorder() const
{
	return bottomBorder;
}

void Widget::setBottomBorder(Uint8 value)
{
	bottomBorder = value;
}

const Color & Widget::getTextColor() const
{
	return textColor;
}

void Widget::setTextColor(const Color & value)
{
	textColor = value;
}

const Color & Widget::getBackgroundColor() const
{
	return backgroundColor;
}

void Widget::setBackgroundColor(const Color & value)
{
	backgroundColor = value;
}
} // namespace yep

